package cn.lili.modules.grab.xdxt;

import cn.lili.common.enums.SwitchEnum;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.exchange.AmqpExchangeProperties;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.grab.GrabGoodsParam;
import cn.lili.modules.grab.GrabNoticeParam;
import cn.lili.modules.grab.dingdong.base.BaseResult;
import cn.lili.modules.grab.dingdong.res.goods.DetailRequest;
import cn.lili.modules.grab.dingdong.res.goods.GoodsQueryRequest;
import cn.lili.modules.grab.enums.SourceEnums;
import cn.lili.modules.grab.enums.StatusEnums;
import cn.lili.modules.grab.factory.goods.GrabGoodsFactory;
import cn.lili.modules.grab.factory.notice.GrabNoticeService;
import cn.lili.modules.grab.xdxt.config.XdxtConfig;
import cn.lili.modules.grab.xdxt.res.goods.ListGoodsRes;
import cn.lili.modules.grab.xdxt.service.XdxtNoticeService;
import cn.lili.modules.order.order.client.OrderClient;
import cn.lili.modules.order.order.client.OrderItemClient;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.system.client.LogisticsClient;
import cn.lili.modules.system.entity.dos.Logistics;
import cn.lili.routing.GoodsRoutingKey;
import cn.lili.util.AmqpMessage;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Component
@Slf4j
public class GrabXdxtNoticeServiceImpl implements GrabNoticeService {

    @Resource
    private GoodsSkuService goodsSkuService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private GrabGoodsFactory grabGoodsFactory;
    @Resource
    private ApplicationEventPublisher applicationEventPublisher;
    @Resource
    private AmqpExchangeProperties amqpExchangeProperties;
    @Resource
    private LogisticsClient logisticsClient;
    @Resource
    private OrderItemClient orderItemClient;
    @Resource
    private OrderClient orderClient;
    @Resource
    private XdxtNoticeService xdxtNoticeService;

    @Override
    public SourceEnums step() {
        return SourceEnums.XDXT_NOTICE;
    }

    /**
     * 订单回调通知接口
     *
     * @param grabParam 通知参数
     */
    @Override
    public BaseResult orderCallback(GrabNoticeParam grabParam) {
        JSONObject data = xdxtNoticeService.orderCallback();
        log.info("盛创汇联--订单信息修改通知入参----{}", JSONObject.toJSONString(data));
        if(data.getJSONArray("result")==null || data.getJSONArray("result").isEmpty()){
            return null;
        }

        JSONObject changesContent = data.getJSONArray("result").getJSONObject(0).getJSONArray("changesContent").getJSONObject(0);
        JSONObject orderDelivered = changesContent.getJSONArray("orderDeliveredList").getJSONObject(0);

        Logistics logistics = logisticsClient.getByName(orderDelivered.getString("expName"));
        if (logistics == null) {
            logistics = new Logistics();
            logistics.setCode(orderDelivered.getString("expCode"));
            logistics.setDisabled(SwitchEnum.OPEN.name());
            logistics.setName(orderDelivered.getString("expName"));
            logistics.setStandBy("true");
            String id = logisticsClient.save(logistics);
            logistics.setId(id);
        }

        //订单发货
        String orderDetailId = orderDelivered.getJSONArray("packageList").getJSONObject(0).getString("orderDetailId");
        OrderItem orderItem = orderItemClient.getByIdVal(orderDetailId);
        orderClient.delivery(orderItem.getOrderSn(), orderDelivered.getString("expNo"), logistics.getId());


        //处理订单回调逻辑
        return BaseResult.builder()
                .status(StatusEnums.STATUS_200.getCode())
                .msg(StatusEnums.STATUS_200.getDes())
                .build();
    }

    /**
     * 商品信息修改通知
     *
     * @param grabParam 参数
     */
    @Override
    public BaseResult goodsCallback(GrabNoticeParam grabParam) {
        log.info("盛创汇联--商品信息修改通知入参----{}", JSONObject.toJSONString(grabParam));
        //获取变动数据
        JSONObject data = xdxtNoticeService.goodsCallback();
        log.info("盛创汇联222222222--商品信息修改查询返回--{}",JSONObject.toJSONString(data));
        JSONArray result = data.getJSONArray("result");
        log.info("盛创汇联--商品信息修改查询返回--{}",JSONObject.toJSONString(result));
        if(result==null || result.isEmpty()){
            return null;
        }

        result.forEach(value -> {
            JSONObject obj = JSONObject.parseObject(String.valueOf(value));
            //买一单会推送一个库存消息，导致库存下架，所有这里return
            if("GOODS_UPDATE_STOCK".equals(obj.getString("eventKey"))){
                return;
            }
            if ("GOODS_DOWN_STATE".equals(obj.getString("eventKey")) || "GOODS_UP_STATE".equals(obj.getString("eventKey"))) {
                //商品下架/上架
                JSONArray changesContent = obj.getJSONArray("changesContent");
                changesContent.forEach(e -> {
                    JSONObject id = JSONObject.parseObject(e.toString());
                    updateGoodsBy(id.get("id").toString());
                });
            }else if("GOODS_ADD_ITEM".equals(obj.getString("eventKey"))){
                //商品添加规格
                JSONArray changesContent = obj.getJSONArray("changesContent");
                changesContent.forEach(e -> {
                    JSONObject code = JSONObject.parseObject(e.toString());
                    updateGoodsByGoodsNo(code.get("goodsId").toString());
                });
            }else if("GOODS_REMOVE_ITEM".equals(obj.getString("eventKey"))){
                //商品移除规格
                JSONArray changesContent = obj.getJSONArray("changesContent");
                changesContent.forEach(e -> {
                    JSONObject code = JSONObject.parseObject(e.toString());
                    deleteGoodsByGoodsNo(code.get("code").toString());
                });
            } else {
                //规格价格变动  商品上架  规格库存变动
                JSONArray changesContent = obj.getJSONArray("changesContent");
                changesContent.forEach(e -> {
                    JSONObject code = JSONObject.parseObject(e.toString());
                    updateGoodsBySkuNo(code.get("code").toString());
                });
            }
        });
        return null;
    }

    /**
     * 移除规格
     * */
    public void deleteGoodsByGoodsNo(String code) {
        LambdaQueryWrapper<GoodsSku> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GoodsSku::getThirdPartyPlatformType, "3");
        queryWrapper.eq(GoodsSku::getThirdPartyPlatformId, code);
        List<GoodsSku> goodsSkus = goodsSkuService.getBaseMapper().selectList(queryWrapper);
        if (goodsSkus == null) {
            return;
        }
        //删除SKU
        List<String> skuIds = goodsSkus.stream().map(GoodsSku::getId).collect(Collectors.toList());
        goodsSkuService.delete(skuIds);

        //下架商品
        List<String> goodsIds = goodsSkus.stream().map(GoodsSku::getGoodsId).collect(Collectors.toList());
        for (String goodsId:goodsIds) {
            Goods goods = new Goods();
            goods.setId(goodsId);
            goods.setMarketEnable("DOWN");
            goods.setAuthFlag(GoodsAuthEnum.TOBEAUDITED.name());
            goodsService.updateGoods(goods);
        }

        //清除es
        applicationEventPublisher.publishEvent(TransactionCommitSendMQEvent
                .builder()
                .source("商品删除")
                .exchange(amqpExchangeProperties.getGoods())
                .routingKey(GoodsRoutingKey.GOODS_DELETE)
                .message(goodsIds)
                .build());
    }

    /**
     * 根据规格查询商品并重新导入
     *
     * @param goodsNo 商品code
     */
    public void updateGoodsByGoodsNo(String goodsNo) {
        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Goods::getThirdPartyPlatformType, "3");
        queryWrapper.eq(Goods::getThirdPartyPlatformId, goodsNo);
        List<Goods> goodsList = goodsService.getBaseMapper().selectList(queryWrapper);
        if (goodsList == null) {
            return;
        }

        for (Goods goods:goodsList) {
            ArrayList<Long> arrayList = new ArrayList<>();
            arrayList.add(Long.parseLong(goods.getThirdPartyPlatformId()));
            //重新拉取商品
            ListGoodsRes.Query query = new ListGoodsRes.Query();
            query.setQueryType("1");
            query.setGoodsIds(arrayList);

            ListGoodsRes listGoodsRes = new ListGoodsRes();
            listGoodsRes.setQuery(query);

            GrabGoodsParam grabParam = new GrabGoodsParam();
            grabParam.setCode(SourceEnums.XDXT_GOODS.name());
            grabParam.setStoreId(goods.getStoreId());
            grabParam.setFlag(false);
            grabParam.setListGoodsRes(listGoodsRes);
            grabGoodsFactory.generateGoodsFactory(grabParam);
        }
    }

    /**
     * 根据规格查询商品并重新导入
     *
     * @param code 商品code
     */
    public void updateGoodsBySkuNo(String code) {
        LambdaQueryWrapper<GoodsSku> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GoodsSku::getThirdPartyPlatformType, "3");
        queryWrapper.eq(GoodsSku::getThirdPartyPlatformId, code);
        List<GoodsSku> goodsSkus = goodsSkuService.getBaseMapper().selectList(queryWrapper);
        if (goodsSkus == null) {
            return;
        }

        for (GoodsSku goodsSku:goodsSkus) {
            Goods goods = goodsService.getById(goodsSku.getGoodsId());
            if (goods == null) {
                return;
            }

            ArrayList<Long> arrayList = new ArrayList<>();
            arrayList.add(Long.parseLong(goods.getThirdPartyPlatformId()));
            //重新拉取商品
            ListGoodsRes.Query query = new ListGoodsRes.Query();
            query.setQueryType("1");
            query.setGoodsIds(arrayList);

            ListGoodsRes listGoodsRes = new ListGoodsRes();
            listGoodsRes.setQuery(query);

            GrabGoodsParam grabParam = new GrabGoodsParam();
            grabParam.setCode(SourceEnums.XDXT_GOODS.name());
            grabParam.setStoreId(goods.getStoreId());
            grabParam.setFlag(false);
            grabParam.setListGoodsRes(listGoodsRes);
            grabGoodsFactory.generateGoodsFactory(grabParam);
        }
    }

    /**
     * 下架
     *
     * @param id 第三方商品ID
     */
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void updateGoodsBy(String id) {
        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Goods::getThirdPartyPlatformType, "3");
        queryWrapper.eq(Goods::getThirdPartyPlatformId, id);
        List<Goods> goodsList = goodsService.getBaseMapper().selectList(queryWrapper);
        for (Goods goods:goodsList) {
            goods.setMarketEnable("DOWN");
            goods.setAuthFlag(GoodsAuthEnum.TOBEAUDITED.name());
            goodsService.getBaseMapper().updateById(goods);

            //下架sku
            List<GoodsSku> skuList = goodsSkuService.getGoodsSkuListByGoodsId(goods.getId());
            skuList.forEach(e->{
                e.setMarketEnable("DOWN");
                e.setAuthFlag(GoodsAuthEnum.TOBEAUDITED.name());
                goodsSkuService.getBaseMapper().updateById(e);
            });

            // 发送删除es商品的信息
            List<String> goodIds = new ArrayList<>();
            goodIds.add(goods.getId());
            applicationEventPublisher.publishEvent(TransactionCommitSendMQEvent
                    .builder()
                    .source("商品删除")
                    .exchange(amqpExchangeProperties.getGoods())
                    .routingKey(GoodsRoutingKey.GOODS_DELETE)
                    .message(goodIds)
                    .build());
        }
    }
}
